<template>
  <h3>基础汇率</h3>
  <el-form :inline="true" :model="formInline" class="demo-form-inline">
    <el-form-item label="原始币种">
      <el-select
          v-model="formInline.fromCode"
          placeholder="选择原始币种"
          clearable
          @change="handleCurrencyChange">
        <el-option
            v-for="(name, code) in currencyOptions"
            :key="code"
            :label="`${code} (${name})`"
            :value="code"
        />
      </el-select>
    </el-form-item>

    <el-form-item label="目标币种">
      <el-select
          v-model="formInline.toCode"
          placeholder="选择目标币种"
          clearable
          @change="handleCurrencyChange">
        <el-option
            v-for="(name, code) in currencyOptions"
            :key="code"
            :label="`${code} (${name})`"
            :value="code"
        />
      </el-select>
    </el-form-item>

    <el-form-item label="日期范围">
      <el-config-provider :locale="locale">
        <el-date-picker
            v-model="formInline.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD HH:mm:ss"
            :default-time="defaultTime"
            format="YYYY年MM月DD日"
            :shortcuts="shortcuts"
            :first-day-of-week="1"
            :locale="locale"
            @change="handleDateChange"
            clearable
        />
      </el-config-provider>
    </el-form-item>

    <el-form-item label="翻转汇率">
      <el-switch
          v-model="formInline.isChangeCode"
          @change="handleChangeCodeSwitch"
      />
    </el-form-item>
  </el-form>

  <!-- 折线图组件 -->
  <div ref="chartRef" style="width: 100%; height: 600px"></div>
</template>

<script lang="ts" setup>
import {ref, reactive, onMounted} from 'vue'
import type {DateModelType} from 'element-plus'
import type {Language} from 'element-plus/es/locale'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import axios from 'axios'
import * as echarts from 'echarts'

interface RateData {
  date: string
  rate: number
}

const chartRef = ref<HTMLElement>()
let myChart: echarts.ECharts | null = null
const currencyOptions = ref<Record<string, string>>({})
const minRate = ref<number>(6.8)
const maxRate = ref<number>(7.4)
const locale = ref<Language>(zhCn)

const formInline = reactive({
  fromCode: 'CNY',
  toCode: 'JPY',
  dateRange: null as [string, string] | null,
  isChangeCode: false
})

// 设置默认时间
const defaultTime = [
  new Date(2000, 1, 1, 0, 0, 0),
  new Date(2000, 1, 1, 23, 59, 59)
]

// 快捷选项
const shortcuts = [
  {
    text: '最近一周',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
  },
  {
    text: '最近一个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setMonth(start.getMonth() - 1)
      return [start, end]
    },
  },
  {
    text: '最近三个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setMonth(start.getMonth() - 3)
      return [start, end]
    },
  },
]

// 获取币种列表
const fetchCurrencyOptions = async () => {
  try {
    const response = await axios.get('api/rate/currency')
    if (response.data.code === 200) {
      currencyOptions.value = response.data.data
    }
  } catch (error) {
    console.error('获取币种列表失败:', error)
  }
}

// 初始化图表
const initChart = (data: RateData[]) => {
  if (!chartRef.value) return

  if (myChart) {
    myChart.dispose()
  }

  myChart = echarts.init(chartRef.value)

  const dates = data.map(item => item.date)
  const rates = data.map(item => item.rate)

  const option = {
    title: {
      text: '汇率走势图'
    },
    tooltip: {
      trigger: 'axis',
      formatter: '{b}<br/>汇率: {c}'
    },
    xAxis: {
      type: 'category',
      data: dates,
      axisLabel: {
        rotate: 45
      }
    },
    yAxis: {
      type: 'value',
      name: '汇率',
      min: minRate.value,
      max: maxRate.value,
      axisLabel: {
        formatter: '{value}'
      }
    },
    dataZoom: [
      {
        type: 'slider',
        show: true,
        start: 0,
        end: 100
      },
      {
        type: 'inside',
        start: 0,
        end: 100
      }
    ],
    series: [
      {
        name: '汇率',
        type: 'line',
        data: rates,
        smooth: true,
        markPoint: {
          data: [
            {type: 'max', name: '最大值'},
            {type: 'min', name: '最小值'}
          ]
        }
      }
    ]
  }

  myChart.setOption(option)

  window.addEventListener('resize', () => {
    myChart?.resize()
  })
}

// 获取汇率数据
const fetchRateData = async () => {
  if (!formInline.dateRange) return

  try {
    const [startDate, endDate] = formInline.dateRange
    const response = await axios.get('api/rate/rate_date', {
      params: {
        start_date: startDate,
        end_date: endDate,
        from_code: formInline.fromCode,
        to_code: formInline.toCode,
        change_code: formInline.isChangeCode ? "1" : ""
      }
    })

    if (response.data.code === 200) {
      const data = Object.entries(response.data.data).map(([date, rate]) => ({
        date,
        rate
      }))
      minRate.value = Math.floor(response.data.min * 100) / 100
      maxRate.value = Math.ceil(response.data.max * 100) / 100
      initChart(data)
    }
  } catch (error) {
    console.error('获取汇率数据失败:', error)
  }
}

// 处理日期变化
const handleDateChange = (val: DateModelType) => {
  if (val) {
    fetchRateData()
  }
}

// 处理币种变化
const handleCurrencyChange = () => {
  if (formInline.dateRange) {
    fetchRateData()
  }
}

// 处理环比开关变化
const handleChangeCodeSwitch = () => {
  if (formInline.dateRange) {
    fetchRateData()
  }
}

// 获取默认日期范围
const getDefaultDateRange = () => {
  const end = new Date()
  const start = new Date()
  start.setMonth(start.getMonth() - 1)

  const formatDate = (date: Date) => {
    return date.toISOString().slice(0, 23).replace('T', ' ')
  }

  return [formatDate(start), formatDate(end)]
}

onMounted(() => {
  fetchCurrencyOptions()
  formInline.dateRange = getDefaultDateRange()
  fetchRateData()
})
</script>

<style>
.demo-form-inline .el-select {
  --el-select-width: 220px;
}

.demo-form-inline .el-date-editor--daterange {
  --el-date-editor-width: 360px;
}
</style>
